package com.gnerv.pabu.basic.core.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gnerv.pabu.basic.core.dto.PersonalDTO;
import com.gnerv.pabu.basic.core.dto.UpdatePasswordDTO;
import com.gnerv.pabu.basic.core.dto.UserDTO;
import com.gnerv.pabu.basic.core.dto.UserInfoDTO;
import com.gnerv.pabu.basic.core.dto.UserSaveDTO;
import com.gnerv.pabu.basic.core.dto.UserSearchDTO;
import com.gnerv.pabu.basic.core.entity.User;
import com.gnerv.pabu.basic.core.entity.UserInfo;
import com.gnerv.pabu.basic.core.exception.BusinessException;
import com.gnerv.pabu.basic.core.mapper.UserInfoMapper;
import com.gnerv.pabu.basic.core.mapper.UserMapper;
import com.gnerv.pabu.basic.core.service.IOrgService;
import com.gnerv.pabu.basic.core.service.IUserService;
import com.gnerv.pabu.basic.core.utils.EncryptionUtils;
import com.gnerv.pabu.basic.core.utils.UUIDUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 基础平台-用户 service 实现类
 *
 * @author zhang
 * @date 2019/11/30
 **/
@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private IOrgService orgService;

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean saveUser(UserSaveDTO userSaveDTO) {
        String ukId = userSaveDTO.getUkId();
        if (StringUtils.isEmpty(ukId)) {
            this.createUser(userSaveDTO);
        } else {
            this.updateUser(userSaveDTO);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean createUser(UserSaveDTO userSaveDTO) {
        if (StringUtils.isEmpty(userSaveDTO.getOrgId())) {
            throw new BusinessException("所属机构不能为空！");
        }
        //添加用户信息，同时添加用户详情信息，和角色信息
        User user = userSaveDTO.convert();
        user.setUkId(UUIDUtils.getLower());
        user.setSalt(UUIDUtils.getLower());
        //密码加密处理
        if ("1".equals(userSaveDTO.getPasswordType())) {
            String encryption = EncryptionUtils.encryption("123456", user.getSalt());
            user.setPassword(encryption);
        }
        if ("2".equals(userSaveDTO.getPasswordType())) {
            String encryption = EncryptionUtils.encryption(UUIDUtils.getLower().substring(0, 5), user.getSalt());
            user.setPassword(encryption);
        }
        if ("3".equals(userSaveDTO.getPasswordType())) {
            String encryption = EncryptionUtils.encryption(user.getPassword(), user.getSalt());
            user.setPassword(encryption);
        }
        userMapper.createUser(user);

        orgService.bindOrgUser(userSaveDTO.getOrgId(), user.getUkId());

        List<String> roleIds = userSaveDTO.getRoleIds();
        if (!CollectionUtils.isEmpty(roleIds)) {
            this.bindUserRole(user.getUkId(), roleIds);
        }

        UserInfoDTO userInfoDTO = userSaveDTO.getUserInfo();
        if (!StringUtils.isEmpty(userInfoDTO)) {
            UserInfo userInfo = userInfoDTO.convert();
            userInfo.setUserId(user.getUkId());
            userInfoMapper.insert(userInfo);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean deleteUser(String userId) {
        //删除用户同时 删除用户详情 与 绑定的角色
        this.unBindUserRole(userId);
        userInfoMapper.deleteUserInfo(userId);
        userMapper.deleteUser(userId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean updateUser(UserSaveDTO userSaveDTO) {
        if (!StringUtils.isEmpty(userSaveDTO.getOrgId())) {
            throw new BusinessException("所属机构不能为空！");
        }

        User user = userSaveDTO.convert();
        user.setGmtModified(LocalDateTime.now());
        // 不允许修改账号
        user.setAccount(null);
        // 不允许修改密码
        user.setPassword(null);
        userMapper.updateById(user);

        String userId = user.getUkId();
        orgService.unBindUserOrg(userId);
        orgService.bindOrgUser(userSaveDTO.getOrgId(), userId);

        List<String> roleIds = userSaveDTO.getRoleIds();
        if (!CollectionUtils.isEmpty(roleIds)) {
            this.unBindUserRole(userId);
            this.bindUserRole(userId, roleIds);
        }

        UserInfoDTO userInfoDTO = userSaveDTO.getUserInfo();
        if (StringUtils.isEmpty(userInfoDTO)) {
            UserInfo userInfo = userInfoDTO.convert();
            userInfo.setUserId(userId);
            userInfo.setGmtModified(LocalDateTime.now());
            userInfoMapper.updateById(userInfo);
        }
        return true;
    }

    @Override
    public UserDTO selectUser(String userId) {
        return userMapper.selectUser(userId);
    }

    @Override
    public Page<UserDTO> listUser(Integer current, Integer size, UserSearchDTO searchUser) {
        Page<User> page = new Page<>(current, size);
        Page<UserDTO> listUser = userMapper.listUser(page, searchUser);
        return listUser;
    }

    @Override
    public List<UserDTO> listUsersByOrgId(String orgId) {
        List<UserDTO> users = userMapper.listUsersByOrgId(orgId);
        return users;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean bindUserRole(String userId, List<String> roleIds) {
        userMapper.bindUserRole(userId, roleIds);
        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean unBindUserRole(String userId) {
        userMapper.unBindUserRole(userId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean updatePassword(String userId, UpdatePasswordDTO passwordDTO) {
        UserDTO userDTO = userMapper.selectUser(userId);
        String oldPassWord = passwordDTO.getOldPassWord();
        String newPassWord = passwordDTO.getNewPassWord();

        String oldEncryption = EncryptionUtils.encryption(oldPassWord, userDTO.getSalt());
        String newEncryption = EncryptionUtils.encryption(newPassWord, userDTO.getSalt());
        userMapper.updatePassword(userId, oldEncryption, newEncryption);
        return true;
    }


    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean resetPassword(String userId, String passwordType, String password) {
        User user = new User();
        user.setUkId(userId);
        String encryption;
        String salt = UUIDUtils.getLower();
        //密码加密处理
        if ("1".equals(passwordType)) {
            encryption = EncryptionUtils.encryption("123456", salt);
            user.setPassword(encryption);
            user.setSalt(salt);
        }
        if ("2".equals(passwordType)) {
            encryption = EncryptionUtils.encryption(UUIDUtils.getLower().substring(0, 5), salt);
            user.setPassword(encryption);
            user.setSalt(salt);
        }
        if ("3".equals(passwordType)) {
            encryption = EncryptionUtils.encryption(password, salt);
            user.setPassword(encryption);
            user.setSalt(salt);
        }
        userMapper.updateById(user);
        return true;
    }

    @Override
    public List<UserDTO> listUsersByRoleId(String roleId) {
        List<UserDTO> users = userMapper.listUsersByRoleId(roleId);
        return users;
    }

    @Override
    public boolean updateUserStatus(String userId, Integer status) {
        userMapper.updateUserStatus(userId, status);
        return true;
    }

    @Override
    public PersonalDTO selectPersonal(String userId) {
        PersonalDTO personal = userMapper.selectPersonal(userId);
        return personal;
    }

}
